import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import numpy as np

warnings.filterwarnings('ignore')

class ClusterUtils(object):
    def __init__(self):
        self.df = pd.read_csv('./scenic_data.csv')

    def get_cluster(self):
        # 提取特征并标准化
        features = self.df[['non_weekend_ratio', 'out_province_ratio', 'elderly_ratio']]
        scaler = StandardScaler()
        scaled_features = scaler.fit_transform(features)
        
        # 使用K-Means聚类
        kmeans = KMeans(n_clusters=4, random_state=42)
        self.df['cluster'] = kmeans.fit_predict(scaled_features)
        
        # 获取聚类中心
        centers = kmeans.cluster_centers_
        
        # 将聚类中心转换为DataFrame
        centers_df = pd.DataFrame(centers, columns=features.columns)
        centers_df['cluster'] = [f'Cluster {i}' for i in range(centers.shape[0])]
        
        # 将宽格式转换为长格式（适合seaborn绘图）
        centers_long = centers_df.melt(id_vars='cluster', var_name='feature', value_name='value')
        
        # 绘制分组柱状图
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为SimHei显示中文
        plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
        colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#4b0082']  # 蓝、橙、绿、紫
        
        plt.figure(figsize=(10, 6))
        barplot = sns.barplot(x='feature', y='value', hue='cluster', data=centers_long, palette=colors)
        plt.title('聚类中心特征对比')
        plt.ylabel('比例')
        plt.ylim(0, 1)
        plt.legend(title='聚类', bbox_to_anchor=(1.05, 1), loc='upper left')
        
        # 添加数值标签
        for p in barplot.patches:
            height = p.get_height()
            plt.text(p.get_x() + p.get_width() / 2, height + 0.02, f'{height:.2f}', ha='center')
        
        plt.tight_layout()
        plt.show()

if __name__ == '__main__':
    cu = ClusterUtils()
    cu.get_cluster()